import frappe
from frappe import _
from erpnext.selling.doctype.sales_order.sales_order import SalesOrder as OriginalSalesOrder
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from frappe.types import DF

class SalesOrder(OriginalSalesOrder):
    """覆盖Sales Order类，添加自定义状态"""
    
    # 重新定义status字段，添加自定义状态
    if TYPE_CHECKING:
        status: DF.Literal[
            "",
            "Draft",
            "On Hold", 
            "To Bill",
            "To Deliver",
            "Completed",
            "Cancelled",
            "Closed",
        ]
    
    def validate(self):
        """验证状态变更"""
        super().validate()
        self._normalize_status_after_submit_if_needed()
    
    def get_status_color(self):
        """获取状态颜色"""
        color_map = {
            "Draft": "red",
            "On Hold": "orange",
            # 保留映射但不再使用 To Receive
            "To Bill": "orange",
            "To Deliver": "orange",
            "Completed": "green",
            "Cancelled": "red",
            "Closed": "blue",
        }
        return color_map.get(self.status, "blue")

    def on_submit(self):
        """提交后将状态规范为 To Deliver（待发货）"""
        super().on_submit()
        try:
            if self.docstatus == 1:
                # 标准流程可能设置为 'To Deliver and Bill' 等旧值；统一改为 'To Deliver'
                allowed_final = {"To Deliver", "To Bill", "Completed", "On Hold", "Closed", "Cancelled"}
                if self.status not in allowed_final or self.status == "To Pay":
                    # 使用 db_set 避免触发额外 hooks 与二次更新
                    self.db_set("status", "To Deliver", update_modified=False)
        except Exception as e:
            frappe.logger().error(f"设置销售订单 {self.name} 提交后状态为 To Deliver 失败: {str(e)}")

    def before_submit(self):
        """提交前兜底一次，防止核心逻辑在 on_submit 之后覆盖"""
        try:
            # 仅当仍为草稿或非法状态时设置
            if not self.status or self.status in {"Draft", "To Pay", "To Deliver and Bill"}:
                self.status = "To Deliver"
        except Exception:
            pass

    def on_update_after_submit(self):
        """提交后任意更新再次兜底，确保不会回到旧状态"""
        self._normalize_status_after_submit_if_needed()

    # --- helpers ---
    def _normalize_status_after_submit_if_needed(self):
        try:
            if getattr(self, "docstatus", 0) != 1:
                return
            allowed_final = {"To Deliver", "To Bill", "Completed", "On Hold", "Closed", "Cancelled"}
            if self.status not in allowed_final or self.status == "To Pay" or self.status == "To Deliver and Bill":
                # 使用 db_set，避免再次触发生命周期方法
                self.db_set("status", "To Deliver", update_modified=False)
        except Exception:
            # 静默兜底
            pass
